package com.app.simpsonux;


import android.app.Activity;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.sip.SipAudioCall;
import android.net.sip.SipException;
import android.net.sip.SipManager;
import android.net.sip.SipProfile;
import android.net.sip.SipRegistrationListener;
import android.net.sip.SipSession;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.*;

import java.text.ParseException;

public class DialerViewActivity extends Activity implements View.OnClickListener 
{
    public String mUserId       = "";
    public String mUserPasswd   = "";
    public String mStrCalleeNum = "";
    public String mServerAddr   = "";
    
    public static final int RESULT_SUCCESS = 0;
    public static final int RESULT_FAIL    = 1;
    public static final int RESULT_REMOVE  = 2;
    
    public String          sipAddress      = null;
    public SipManager      sipManager      = null;
    public SipProfile      sipProfile      = null;
    public SipSession      sipSession      = null;
    public SipAudioCall    sipAudioCall    = null;
    public SipCallListener sipCallListener = null;
    
    public static Context mContext;

    protected void initOnClickListener()
    {
        ( (Button)findViewById( R.id.btnkeyzero  ) ).setOnClickListener( this );
        ( (Button)findViewById( R.id.btnkeyone   ) ).setOnClickListener( this );
        ( (Button)findViewById( R.id.btnkeytwo   ) ).setOnClickListener( this );
        ( (Button)findViewById( R.id.btnkeythree ) ).setOnClickListener( this );
        ( (Button)findViewById( R.id.btnkeyfour  ) ).setOnClickListener( this );
        ( (Button)findViewById( R.id.btnkeyfive  ) ).setOnClickListener( this );
        ( (Button)findViewById( R.id.btnkeysix   ) ).setOnClickListener( this );
        ( (Button)findViewById( R.id.btnkeyseven ) ).setOnClickListener( this );
        ( (Button)findViewById( R.id.btnkeyeight ) ).setOnClickListener( this );
        ( (Button)findViewById( R.id.btnkeynine  ) ).setOnClickListener( this );
        ( (Button)findViewById( R.id.btnkeysharp ) ).setOnClickListener( this );
        ( (Button)findViewById( R.id.btnkeystar  ) ).setOnClickListener( this );
        ( (Button)findViewById( R.id.btnkeycall  ) ).setOnClickListener( this );
        ( (Button)findViewById( R.id.btnkeydrop  ) ).setOnClickListener( this );
        ( (Button)findViewById( R.id.btnkeyleave ) ).setOnClickListener( this );
        ( (Button)findViewById( R.id.btnkeyrm    ) ).setOnClickListener( this );
        ( (Button)findViewById( R.id.btnkeydel   ) ).setOnClickListener( this );
        ( (Button)findViewById( R.id.btnkeysetup ) ).setOnClickListener( this );
    }
    
    public void initSipListener()
    {
        IntentFilter sFilter = new IntentFilter();
        
        Log.i( "initSipListener", "1" );
        
        sFilter.addAction("android.SipDemo.INCOMING_CALL");
        
        sipCallListener = new SipCallListener();
        Log.i( "initSipListener", "2" );
        registerReceiver( sipCallListener, sFilter );
    }
    
    public boolean initSipManager()
    {
        if( sipManager == null )
        {
            sipManager = SipManager.newInstance( this );
            
            if( sipManager == null )
            {
                Log.v( "initSipManager",
                        "isApiSupported: " + new Boolean(SipManager.isApiSupported(this)).toString());
                Log.v( "initSipManager",
                        "isSipWifiOnly: " + new Boolean(SipManager.isSipWifiOnly(this)).toString());
                Log.v( "initSipManager",
                        "isVoipSupported: " + new Boolean(SipManager.isVoipSupported(this)).toString());
                Log.i( "initSipManager",
                        "Can't acquire SipManager Instance.");
                return false;
            }
            else
            {
                Log.v("initSipManager", "manager: " + sipManager.toString());
            }
        }
        Log.i("initSipManager", "1");
        
        return initSipUserInfo( sipManager, sipProfile );
    }
    
    @Override
    protected void onCreate( Bundle savedInstanceState )
    {
        UXParcel sParcel = null;
        super.onCreate( savedInstanceState );
        setContentView( R.layout.dialerview );

        // get user id
        sParcel = getIntent().getExtras().getParcelable( getString( R.string.intent_userinfo ) );
        
        mUserId     = sParcel.mUserId;
        mUserPasswd = sParcel.mUserPwd;
        mServerAddr = sParcel.mServerAddr;
        
        mStrCalleeNum = new String("");

        initOnClickListener();
        
        sipManager = SipManager.newInstance(getApplicationContext());
        
        initSipListener();
        
        initSipManager();
        
        mContext = this;
    }
    
    @Override
    public void onClick(View v)
    {
        EditText sStateEditor = (EditText)findViewById(R.id.editTextState);
        Intent   sIntent = null;
        UXParcel sParcel = null;
        switch( v.getId() )
        {
        case R.id.btnkeyzero: /* Key : Zero */
            mStrCalleeNum += "0";
            sStateEditor.setText( mStrCalleeNum );
            break;
        case R.id.btnkeyone: /* Key : One */
            mStrCalleeNum += "1";
            sStateEditor.setText( mStrCalleeNum );
            break;
        case R.id.btnkeytwo: /* Key : Two */
            mStrCalleeNum += "2";
            sStateEditor.setText( mStrCalleeNum );
            break;
        case R.id.btnkeythree: /* Key : Three */
            mStrCalleeNum += "3";
            sStateEditor.setText( mStrCalleeNum );
            break;
        case R.id.btnkeyfour: /* Key : Four */
            mStrCalleeNum += "4";
            sStateEditor.setText( mStrCalleeNum );
            break;
        case R.id.btnkeyfive: /* Key : Five */
            mStrCalleeNum += "5";
            sStateEditor.setText( mStrCalleeNum );
            break;
        case R.id.btnkeysix: /* Key : Six */
            mStrCalleeNum += "6";
            sStateEditor.setText( mStrCalleeNum );
            break;
        case R.id.btnkeyseven: /* Key : Seven */
            mStrCalleeNum += "7";
            sStateEditor.setText( mStrCalleeNum );
            break;
        case R.id.btnkeyeight: /* Key : Eight */
            mStrCalleeNum += "8";
            sStateEditor.setText( mStrCalleeNum );
            break;
        case R.id.btnkeynine: /* Key : Nine */
            mStrCalleeNum += "9";
            sStateEditor.setText( mStrCalleeNum );
            break;
        case R.id.btnkeysharp: /* Key : Sharp */
            mStrCalleeNum += "#";
            sStateEditor.setText( mStrCalleeNum );
            break;
        case R.id.btnkeystar: /* Key : Star */
            mStrCalleeNum += "*";
            sStateEditor.setText( mStrCalleeNum );
            break;
        case R.id.btnkeydel:
            if( mStrCalleeNum.length() >= 1 )
            {
                mStrCalleeNum = mStrCalleeNum.substring( 0, mStrCalleeNum.length() - 1 );
                sStateEditor.setText( mStrCalleeNum );
            }
            break;
        case R.id.btnkeyrm:
            mStrCalleeNum = "";
            sStateEditor.setText( mStrCalleeNum );
            break;
        case R.id.btnkeycall:
            if( mStrCalleeNum.length() > 0 )
            {
            	if( makeCall( this.mStrCalleeNum,
            			this.sipManager,
            			this.sipProfile ) == true )
            	{
            		v.setEnabled(false);
            		UXUt.ProgressDlg( mContext, "Processing...", "Please wait." );
            		v.setEnabled(true);
            		sIntent = new Intent( DialerViewActivity.this, CallViewActivity.class );
            		sParcel = new UXParcel();
            		sParcel.mUserId   = this.mUserId;
            		sParcel.mCalleeId = this.mStrCalleeNum;
            		sIntent.putExtra( getString( R.string.intent_userinfo ), sParcel );
            		startActivityForResult( sIntent, RESULT_SUCCESS );
            	}
            }
            break;
        case R.id.btnkeyleave:
        	dropCall();
            if( sipProfile != null )
            {
                closeSipUserInfo( sipManager, sipProfile );
            }
            this.finish();
            break;
        case R.id.btnkeydrop:
        	dropCall();
            break;
        case R.id.btnkeysetup:
            sIntent = new Intent( DialerViewActivity.this, SettingViewActivity.class );
            sParcel = new UXParcel();
            sParcel.mUserId = this.mUserId;
            sIntent.putExtra( getString( R.string.intent_userinfo ), sParcel );
            startActivity( sIntent );
        }
    }
    
    protected void onActivityResult(int requestCode, int resultCode, Intent data)
    {
        switch( resultCode )
        {
        case RESULT_REMOVE:
            finish();
            break;
        case RESULT_SUCCESS:
            break;
        case RESULT_FAIL:
            break;
        }
    }
    
    public String getUserId()
    {
        return mUserId;
    }

    /**
     * Updates the status box at the top of the UI with
     * a messege of your choice.
     * @param status The String to display in the status box.
     **/
    public void updateStatus( final String status )
    {
    	boolean bExecute = false;

    	if( bExecute == false )
    	{
            ( (EditText)findViewById( R.id.editTextState ) ).setText( status );
    	}
    	else
    	{
    		// Be a good citizen.  Make sure UI changes
    		// fire on the UI thread.
    		this.runOnUiThread(new Runnable()
    		{
    			public void run()
    			{
    				TextView labelView
    				= (TextView)findViewById( R.id.editTextState );
    				labelView.setText( status );
    			}
    		});
    	}
    }
    
    /**
     * Updates the status box with the SIP address of
     * the current call.
     * @param call The current, active call.
     **/
    public void updateStatus( SipAudioCall call )
    {
        String useName = call.getPeerProfile().getDisplayName();
        if( useName == null )
        {
            useName = call.getPeerProfile().getUserName();
        }
        updateStatus( useName +
                      "@" +
                      call.getPeerProfile().getSipDomain() );
    }
    
    public boolean initSipUserInfo( SipManager aManager, SipProfile aSipProfile )
    {
        Log.i("initSipUserInfo", "0");
        if( aManager == null )
        {
            Log.i( "initSipUserInfo",
                   "Manager is null." );
            return false;
        }

        Log.i("initSipUserInfo", "1");
        if( aSipProfile != null )
        {
            closeSipUserInfo( aManager, aSipProfile );
        }

        Log.i("initSipUserInfo", "2");
        try
        {
            SipProfile.Builder sBuilder =
                    new SipProfile.Builder( mUserId, mServerAddr );
            
            sBuilder.setPassword( this.mUserPasswd );
            
            aSipProfile = sBuilder.build();

            Log.i("initSipUserInfo", "3");
            Intent sI = new Intent();
            sI.setAction( "android.SipDemo.INCOMING_CALL" );
            PendingIntent sPI = PendingIntent.getBroadcast( this,
                                                            0,
                                                            sI,
                                                            Intent.FILL_IN_DATA );

            Log.i("initSipUserInfo", "4");
            aManager.open( aSipProfile, sPI, null );
            aManager.setRegistrationListener(
                    aSipProfile.getUriString(),
                    new SipRegistrationListener()
                    {
                        @Override
                        public void onRegistering( String aLocalPrfUri )
                        {

                            Log.i( "onRegistering",
                                    getString( R.string.regist_state_ing ) );
                            updateStatus( 
                                getString( R.string.regist_state_ing ) );
                        }
                        
                        @Override
                        public void onRegistrationDone( String aLocalPrfUri,
                                                        long aExiryTime)
                        {

                            Log.i( "onRegistrationDone",
                                   getString( R.string.regist_state_ing ) );
                            updateStatus( 
                                getString( R.string.regist_state_ready ) );
                            
                        }
                        @Override
                        public void onRegistrationFailed( String aLocalPrfUri,
                                                          int    aErrCode,
                                                          String aErrMsg )
                        {

                            Log.i( "onRegistrationFailed",
                                   getString( R.string.regist_state_ing ) );
                            updateStatus(
                                getString( R.string.error_regist_err ) );
                        }
                    } );
        }
        catch( ParseException pe )
        {

            Log.i( "initSipUserInfo",
                    getString( R.string.error_connection_err ) );
            updateStatus( getString( R.string.error_connection_err ) );
            return false;
        }
        catch( SipException se )
        {

            Log.i( "initSipUserInfo",
                    getString( R.string.error_connection_err ) );
            updateStatus( getString( R.string.error_connection_err ) );
            return false;
        }
        
        return true;
    }
    
    public void closeSipUserInfo( SipManager aManager, SipProfile aProfile )
    {
        if( aManager != null )
        {
            try
            {
                if( aProfile != null )
                {
                    aManager.close( aProfile.getUriString() );
                }
            }
            catch( Exception e )
            {
                Log.d( "closeSipUserInfo", "failed to close user info." );
            }
        }
    }
    
    public boolean makeCall( String       aCalleeNum,
                          SipManager   aManager,
                          SipProfile   aSipProfile )
    {
        updateStatus( aCalleeNum );
        try
        {
            SipAudioCall.Listener aListener
                 = new SipAudioCall.Listener()
            {
                @Override
                public void onCallEstablished( SipAudioCall aCall )
                {
                    aCall.startAudio();
                    aCall.setSpeakerMode( true );
                    aCall.toggleMute();
                    updateStatus( aCall );
                }
                
                @Override
                public void onCallEnded( SipAudioCall aCall )
                {
                    updateStatus( getString( R.string.regist_state_ready ) );
                }
            };
            
            sipAudioCall = aManager.makeAudioCall(
                                    aSipProfile.getUriString(),
                                    aCalleeNum,
                                    aListener,
                                    30 );
        }
        catch( Exception e )
        {
            Log.i( "makeCall",
                   "Error when trying to close manager.",
                   e );
            
            if( aSipProfile!= null )
            {
                try
                {
                    aManager.close( aSipProfile.getUriString() );
                }
                catch( Exception me )
                {
                    Log.i( "makeCall",
                           "Error when trying to close manager.",
                           me );
                    me.printStackTrace();
                }
            }
            
            if( sipAudioCall != null )
            {
                sipAudioCall.close();
            }
            return false;
        }
        return true;
    }
    
    public void dropCall()
    {
        if( sipAudioCall != null )
        {
            sipAudioCall.close();
        }
    }
};
